home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / Libraries / PixMaps 1.1 / Example / PixExample.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-07-10  |  9.1 KB  |  359 lines  |  [TEXT/MPS ]

  1.  
  2. /* File PixExample.h
  3.     PixMap manipulation routines, example program.
  4.     Copyright (c) 1996, 1997 by John Montbriand.  All Rights Reserved.
  5.     Permission hereby granted for public use.
  6.         Distribute freely in areas where the laws of copyright apply.
  7.     USE AT YOUR OWN RISK.
  8.     DO NOT DISTRIBUTE MODIFIED COPIES.
  9.     Comments/questions/postcards* to the author at the address:
  10.       John Montbriand
  11.       P.O. Box. 1133
  12.       Saskatoon Saskatchewan Canada
  13.       S7K 3N2
  14.     or by email at:
  15.       tinyjohn@sk.sympatico.ca
  16.     *if you mail a postcard, then I will provide you with technical support
  17.     regarding questions you may have about this file. 
  18. */
  19.  
  20. #include "CSApp.h"
  21. #include "PixMap.h"
  22. #include <Devices.h>
  23. #include <Scrap.h>
  24. #include <String.h>
  25. #include <Strings.h>
  26. #include <StdLib.h>
  27.  
  28.  
  29. /* menu constants */
  30. #define kMenuBar 128
  31. #define mApple 128
  32. #define mFile 129
  33. #define  iRight 1
  34. #define  iLeft 2
  35. #define  iVertical 3
  36. #define  iHorizontal 4
  37. #define  iAngle 5
  38. #define  iDraw 6
  39. #define  iQuit 8
  40. #define mEdit 130
  41.  
  42.  
  43. /* various resource id numbers */
  44. #define kNoMemory 128
  45. #define kWindowID 128
  46. #define kAngleBox 129
  47. #define kAboutBox 130
  48. #define kDefaultPict 128
  49.  
  50.  
  51. /* some ascii keys */
  52. #define ETX ((char) 3) /* end of text, ENTER KEY */
  53. #define CR ((char) 13) /* carriage return, RETURN KEY */
  54.  
  55.  
  56. /* globals */
  57. Boolean gRunning = true;
  58. WindowPtr gWind = NULL;
  59. PixMapHandle gThePix = NULL, gDispPix = NULL;
  60. MenuHandle gEditMenu = NULL;
  61.  
  62.  
  63. /* drawing the pixmap in the window */
  64.  
  65. static Rect* CenterRectangle(Rect* target, Rect* theBox) {
  66.     Rect dr = *target, wr = *theBox, r;
  67.     short left, top;
  68.     left = ((dr.right + dr.left) - (wr.right-wr.left)) / 2;
  69.     top =  ((dr.bottom + dr.top) - (wr.bottom-wr.top)) / 2;
  70.     SetRect(&r, left, top, left+(wr.right-wr.left), top+(wr.bottom-wr.top));
  71.     *theBox = r;
  72.     return theBox;
  73. }
  74.  
  75. /* called whenever the window needs to be re-drawn */
  76. static void MyUpdateProc(WindowPtr window) {
  77.     PixMapHandle pix;
  78.     Rect box;
  79.     if ((pix = gDispPix) == NULL) pix = gThePix;
  80.     box = (**pix).bounds;
  81.     SetPort(gWind);
  82.     BeginUpdate(gWind);
  83.     EraseRect(&gWind->portRect);
  84.     CenterRectangle(&gWind->portRect, &box);
  85.     PlotPixMap(pix, box.left, box.top, srcCopy);
  86.     EndUpdate(gWind);
  87. }
  88.  
  89.  
  90. /* routines for managing the globals, here so the Edit menu's
  91. Undo command can be implemented */
  92. static PixMapHandle GetCurrentPixMap(void) {
  93.     if (gDispPix != NULL) return gDispPix; else return gThePix;
  94. }
  95.  
  96. static void SetNextPixMap(PixMapHandle nextpix) {
  97.     if (gDispPix != NULL) {
  98.         KillPixMap(gThePix);
  99.         gThePix = gDispPix;
  100.         gDispPix = nextpix;
  101.     } else if (gThePix == NULL) {
  102.         gThePix = nextpix;
  103.     } else gDispPix = nextpix;
  104.     SetPort(gWind);
  105.     InvalRect(&gWind->portRect);
  106. }
  107.  
  108.  
  109. /* edit commands for the main window */
  110. static void MyWindowEditFunc(WindowPtr window, short editcmd) {
  111.     switch (editcmd) {
  112.         case iUndo:
  113.             {    PixMapHandle temp;
  114.                 temp = gDispPix;
  115.                 gDispPix = gThePix;
  116.                 gThePix = temp;
  117.                 SetPort(gWind);
  118.                 InvalRect(&gWind->portRect);
  119.             }
  120.             break;
  121.         case iCut:
  122.             MyWindowEditFunc(window, iCopy);
  123.             MyWindowEditFunc(window, iClear);
  124.             break;
  125.         case iCopy:
  126.             {    PixMapHandle pix;
  127.                 PicHandle pic;
  128.                 pix = GetCurrentPixMap();
  129.                 if ((pic = PixMapToPICT(pix)) != NULL) {
  130.                     ZeroScrap();
  131.                     HLock((Handle) pic);
  132.                     PutScrap(GetHandleSize((Handle) pic), 'PICT', (Ptr) (*pic));
  133.                 } else Alert(kNoMemory, NULL);
  134.             }
  135.             break;
  136.         case iPaste:
  137.             {    Handle pic;
  138.                 long offset;
  139.                 PixMapHandle nextpix;
  140.                 pic = NewHandle(0);
  141.                 if (GetScrap(pic, 'PICT', &offset) > sizeof(Picture)) {
  142.                     if ((nextpix = PICTToPixMap((PicHandle) pic, NULL)) != NULL) {
  143.                         SetNextPixMap(nextpix);
  144.                     } else Alert(kNoMemory, NULL);
  145.                 }
  146.                 DisposeHandle(pic);
  147.             }
  148.             break;
  149.         case iClear:
  150.             {    PixMapHandle nextpix;
  151.                 if ((nextpix = PICTToPixMap(GetPicture(kDefaultPict), NULL)) != NULL) {
  152.                     SetNextPixMap(nextpix);
  153.                 } else Alert(kNoMemory, NULL);
  154.             }
  155.             break;
  156.     }
  157. }
  158.  
  159.  
  160. /* dialog handling commands */
  161. short gLastItemHit = 0;
  162. static void MyDialogEventFunc(DialogPtr dialog, EventRecord *ev) {
  163.     if (ev->what == keyDown) {
  164.         char ch;
  165.         ch = (ev->message & charCodeMask);
  166.         if (ch == CR || ch == ETX) {
  167.             ev->what = nullEvent;
  168.             gLastItemHit = ok;
  169.         } else if (strchr("0123456789-.", ch) == NULL) {
  170.             ev->what = nullEvent;
  171.             SysBeep(1);
  172.         }
  173.     }
  174. }
  175.  
  176. static void MyDialogHitProc(DialogPtr dialog, short itemhit, short modifiers) {
  177.     gLastItemHit = itemhit;
  178. }
  179.  
  180.  
  181. /* moveable modal dialog for retrieving a specific angle */
  182. static Boolean GetAngle(float *the_angle) {
  183.     DialogPtr the_dialog;
  184.     WindowPtr mmSave;
  185.     short itemt;
  186.     Handle itemh;
  187.     Rect itemb;
  188.     Str255 itemtext;
  189.     gLastItemHit = 0;
  190.     the_dialog = GetNewDialog(kAngleBox, NULL, (WindowPtr) (-1));
  191.     mmSave = SetMMWindow(the_dialog);
  192.     SelectDialogItemText(the_dialog, 3, 0, 255);
  193.     while (gRunning && (gLastItemHit != ok && gLastItemHit != cancel))
  194.         RunCSApp(GetCaretTime());
  195.     if (gLastItemHit == ok) {
  196.         GetDialogItem(the_dialog, 3, &itemt, &itemh, &itemb);
  197.         GetDialogItemText(itemh, itemtext);
  198.         *the_angle = atof(p2cstr(itemtext));
  199.     }
  200.     SetMMWindow(mmSave);
  201.     DisposeDialog(the_dialog);
  202.     return (gLastItemHit == ok);
  203. }
  204.  
  205.  
  206.  
  207. /* menu handling routine. */
  208.  
  209. static void MyMenuProc(short menu, short item, short modifiers, MenuHandle the_menu) {
  210.     switch (menu) {
  211.         case mApple:
  212.             if (item == 1) {
  213.                 DialogPtr the_dialog;
  214.                 WindowPtr mmSave;
  215.                 gLastItemHit = 0;
  216.                 the_dialog = GetNewDialog(kAboutBox, NULL, (WindowPtr) (-1));
  217.                 mmSave = SetMMWindow(the_dialog);
  218.                 while (gRunning && (gLastItemHit != ok)) RunCSApp(GetCaretTime());
  219.                 SetMMWindow(mmSave);
  220.                 DisposeDialog(the_dialog);
  221.                 gLastItemHit = 0;
  222.             } else if (item > 2) {
  223.                 Str255 deskAccName;
  224.                 GetMenuItemText(the_menu, item, deskAccName);
  225.                 OpenDeskAcc(deskAccName);
  226.             }
  227.             break;
  228.             
  229.         case mFile:
  230.             {    short x, y;
  231.                 float the_angle;
  232.                 PixMapHandle nextpix, oldpix;
  233.                 switch (item) {
  234.                     case iRight:
  235.                         oldpix = GetCurrentPixMap();
  236.                         if ((nextpix = RotatePixRight(oldpix)) != NULL) {
  237.                             SetNextPixMap(nextpix);
  238.                         } else Alert(kNoMemory, NULL);
  239.                         break;
  240.                         
  241.                     case iLeft:
  242.                         oldpix = GetCurrentPixMap();
  243.                         if ((nextpix = RotatePixLeft(oldpix)) != NULL) {
  244.                             SetNextPixMap(nextpix);
  245.                         } else Alert(kNoMemory, NULL);
  246.                         break;
  247.                         
  248.                     case iVertical:
  249.                         oldpix = GetCurrentPixMap();
  250.                         if ((nextpix = FlipPixVertical(oldpix)) != NULL) {
  251.                             SetNextPixMap(nextpix);
  252.                         } else Alert(kNoMemory, NULL);
  253.                         break;
  254.                         
  255.                     case iHorizontal:
  256.                         oldpix = GetCurrentPixMap();
  257.                         if ((nextpix = FlipPixHorizontal(oldpix)) != NULL) {
  258.                             SetNextPixMap(nextpix);
  259.                         } else Alert(kNoMemory, NULL);
  260.                         break;
  261.                         
  262.                     case iAngle:
  263.                         if (GetAngle(&the_angle)) {
  264.                             oldpix = GetCurrentPixMap();
  265.                             x = ((**oldpix).bounds.right + (**oldpix).bounds.left) / 2; 
  266.                             y = ((**oldpix).bounds.bottom + (**oldpix).bounds.top) / 2; 
  267.                             if ((nextpix = RotatePixMap(oldpix, x, y, the_angle)) != NULL) {
  268.                                 SetNextPixMap(nextpix);
  269.                             } else Alert(kNoMemory, NULL);
  270.                         }
  271.                         break;
  272.                         
  273.                     case iDraw:
  274.                         {    Rect r;
  275.                             long i, n;
  276.                             PixMapPort* pxmp;
  277.                             CTabHandle clut;
  278.                             RGBColor the_color;
  279.                             oldpix = GetCurrentPixMap();
  280.                             if ((nextpix = DuplicatePixMap(oldpix)) != NULL) {
  281.                                 r = (**nextpix).bounds;
  282.                                 clut = (**nextpix).pmTable;
  283.                                 if (r.right > r.bottom) n = r.bottom; else n = r.right;
  284.                                 WithPixMap(nextpix, pxmp) {
  285.                                     for (i=0; i<n/10; i++) {
  286.                                         the_color = (**clut).ctTable[i].rgb;
  287.                                         RGBForeColor(&the_color);
  288.                                         FrameRect(&r);
  289.                                         InsetRect(&r, 10, 10);
  290.                                     }
  291.                                 }
  292.                                 SetNextPixMap(nextpix);
  293.                             } else Alert(kNoMemory, NULL);
  294.                         }
  295.                         break;
  296.                     case iQuit:
  297.                         gRunning = false;
  298.                         break;
  299.                 }
  300.             }
  301.             break;
  302.         case mEdit:
  303.             CallEditCommand(item);
  304.             break;
  305.     }
  306.     HiliteMenu(0);
  307. }
  308.  
  309. static void SetMenuItemEnable(MenuHandle theMenu, short theItem, Boolean enabled) {
  310.     if (enabled) EnableItem(theMenu, theItem); else DisableItem(theMenu, theItem);
  311. }
  312.  
  313.  
  314. /* menu reset routine, called before menu selections so we can enable
  315. or disable items.  */
  316. static void MyMenuReset(void) {
  317.     long offset, count;
  318.     if (gWind == FrontWindow()) {
  319.         SetMenuItemEnable(gEditMenu, iPaste,
  320.             (GetScrap(NULL, 'PICT', &offset) > sizeof(Picture)));
  321.         SetMenuItemEnable(gEditMenu, iUndo, (gDispPix != NULL));
  322.     } else {
  323.         count = GetScrap(NULL, 'TEXT', &offset);
  324.         SetMenuItemEnable(gEditMenu, iPaste, (count > 0 && count < 5));
  325.         SetMenuItemEnable(gEditMenu, iUndo, false);
  326.     }
  327. }
  328.  
  329.  
  330. /* moveable modal hook.  we disable the file menu whenever a moveable
  331. modal dialog is up */
  332. static void MyMMHook(Boolean mmactive) {
  333.     SetMenuItemEnable(GetMHandle(mFile), 0, !mmactive);
  334.     DrawMenuBar();
  335. }
  336.  
  337.  
  338. /* main program */
  339. int main(void) {
  340.     if (OpenCSApp(2, 4) != noErr) return 0;
  341.  
  342.     SetMenuFunctions(kMenuBar, MyMenuReset, MyMenuProc);
  343.     AppendResMenu(GetMHandle(mApple), 'DRVR');
  344.     gEditMenu = GetMHandle(mEdit);
  345.     SetWindowRedraw(NULL, MyUpdateProc);
  346.     SetWindowInteraction(NULL, MyWindowEditFunc);
  347.     SetDialogFunctions(MyDialogEventFunc, MyDialogHitProc, NULL);
  348.     SetMMHookProc(MyMMHook);
  349.     gWind = GetNewCWindow(kWindowID, NULL, (WindowPtr) (-1));
  350.         /* clear the window */
  351.     MyWindowEditFunc(gWind, iClear);
  352.  
  353.     while (gRunning) RunCSApp(GetCaretTime());
  354.  
  355. bail:
  356.     CloseCSApp();
  357.     return 0;
  358. }
  359.